<!-- src/views/system/menu/menu.vue -->
<template>
  <div class="menu-management">
    <!-- 搜索表单 -->
    <BaseForm
      ref="searchFormRef"
      v-model:formData="searchFormData"
      :form-list="searchFormList"
      :inline="true"
      label-position="right"
      class="search-form"
    >
      <template #button>
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="handleReset">重置</el-button>
        <el-button type="success" @click="handleAdd">新增</el-button>
      </template>
    </BaseForm>

    <!-- 菜单表格 -->
    <CommonTable :tableData="tableData" :columns="tableColumns" :loading="loading" border>
      <!-- 菜单类型插槽 -->
      <template #menuType="{ row }">
        <el-tag :type="getMenuTypeTagType(row.menuType)" size="small">
          {{ getMenuTypeText(row.menuType) }}
        </el-tag>
      </template>

      <!-- 操作列插槽 -->
      <template #opt="{ row }">
        <el-button size="small" type="primary" @click="handleEdit(row)">编辑</el-button>
        <el-button size="small" type="success" @click="handleAdded(row)">新增</el-button>
        <el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
      </template>
    </CommonTable>

    <!-- 分页 -->
    <!-- <Pagination
      v-model="pagination"
      @update:modelValue="handlePageChange"
      :page-sizes="[10, 20, 50, 100]"
    /> -->

    <!-- 菜单编辑对话框 -->
    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      width="600px"
      @close="handleDialogClose"
    >
      <BaseForm
        ref="menuFormRef"
        v-model:formData="menuFormData"
        :form-list="menuFormList"
        :rules="menuFormRules"
      />
      <template #parentId></template>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSave">保存</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick, watch } from "vue";
import { ElMessage, ElMessageBox, ElTag } from "element-plus";
import BaseForm from "@/components/Form/BaseForm.vue";
import CommonTable from "@/components/Table/CommonTable.vue";
import Pagination from "@/components/Pagination/Pagination.vue";
import menuApi from "@/api/system/menu";
import { changeTree, getObjectValueByName } from "@/utils";

// 引用定义
const searchFormRef = ref<InstanceType<typeof BaseForm> | null>(null);
const menuFormRef = ref<InstanceType<typeof BaseForm> | null>(null);

// 搜索表单数据
const searchFormData = reactive({
  menuName: "",
  status: "",
});

// 搜索表单配置
const searchFormList = [
  {
    key: "menuName",
    tag: "el-input",
    label: "菜单名称",
    props: {
      placeholder: "请输入菜单名称",
      clearable: true,
    },
  },
  {
    key: "status",
    tag: "el-select",
    label: "状态",
    props: {
      placeholder: "请选择状态",
      clearable: true,
      options: [
        { label: "启用", value: "0" },
        { label: "停用", value: "1" },
      ],
    },
  },
];

// 表格列配置
const tableColumns = [
  {
    label: "菜单名称",
    prop: "menuName",
  },
  {
    label: "路径",
    prop: "path",
    width: 150,
  },
  {
    label: "组件路径",
    prop: "component",
    width: 200,
  },
  {
    label: "权限标识",
    prop: "perms",
    width: 200,
  },
  {
    label: "菜单类型",
    prop: "menuType",
    width: 150,
  },
  {
    label: "显示状态",
    prop: "visible",
    filter: (row: any) => (row.visible === "0" ? "显示" : "隐藏"),
    width: 100,
  },
  {
    label: "启用状态",
    prop: "status",
    filter: (row: any) => (row.status === "0" ? "启用" : "停用"),
    width: 100,
  },
  {
    label: "创建时间",
    prop: "createTime",
    width: 180,
  },
  {
    label: "操作",
    width: 220,
    props: {
      fixed: "right",
    },
  },
];

// 获取菜单类型文本
const getMenuTypeText = (type: string) => {
  const typeMap: Record<string, string> = {
    M: "目录",
    C: "菜单",
    F: "按钮",
  };
  return typeMap[type] || "未知";
};

// 获取菜单类型标签类型
const getMenuTypeTagType = (type: string) => {
  const typeMap: Record<string, any> = {
    M: "", // 目录 - 默认样式
    C: "success", // 菜单 - 绿色
    F: "info", // 按钮 - 灰色
  };
  return typeMap[type] || "warning"; // 未知类型 - 橙色
};

// 数据相关
const tableData = ref<any[]>([]);
const loading = ref(false);
const pagination = reactive({
  page: 1,
  limit: 10,
  total: 0,
});

// 对话框相关
const dialogVisible = ref(false);
const dialogTitle = ref("");
const isEdit = ref(false);
const menubList = ref<any[]>([]);

// 菜单表单数据
const menuFormData = reactive({
  id: undefined,
  menuName: "",
  parentId: 0,
  orderNum: 0,
  path: "",
  component: "",
  perms: "",
  status: "0",
  visible: "0",
  menuType: "M",
});

// 处理菜单类型变化
const handleMenuTypeChange = () => {
  const pathItem = getObjectValueByName<FormItem>(menuFormList.value, "path", "key");
  const componentItem = getObjectValueByName<FormItem>(menuFormList.value, "component", "key");
  const permsItem = getObjectValueByName<FormItem>(menuFormList.value, "perms", "key");
  if (pathItem) pathItem.hidden = false;
  if (componentItem) componentItem.hidden = false;
  if (permsItem) permsItem.hidden = false;
  // 根据菜单类型清空不必要的字段
  if (menuFormData.menuType === "F") {
    if (pathItem) pathItem.hidden = true;
    if (componentItem) componentItem.hidden = true;
  } else if (menuFormData.menuType === "M") {
    if (permsItem) permsItem.hidden = true;
    if (componentItem) componentItem.hidden = true;
  } else if (menuFormData.menuType === "C") {
    if (permsItem) permsItem.hidden = true;
  }
};

// 菜单表单配置
const menuFormList = ref([
  {
    key: "parentId",
    tag: "slot",
    label: "上级菜单",
    filter: (row: any) => {
      const menu = menubList.value.find((item: any) => item.id == row.parentId);
      console.log(menu);
      return row.parentId == '0' ? "根目录" : menu?.menuName;
    },
  },
  {
    key: "menuName",
    tag: "el-input",
    label: "菜单名称",
    props: {
      required: true,
      placeholder: "请输入菜单名称",
    },
  },
  {
    key: "menuType",
    tag: "el-select",
    label: "菜单类型",
    props: {
      required: true,
      placeholder: "请选择菜单类型",
      disabled: isEdit.value, // 编辑时禁用
      options: [
        { label: "目录", value: "M" },
        { label: "菜单", value: "C" },
        { label: "按钮", value: "F" },
      ],
      onChange: handleMenuTypeChange,
    },
  },
  {
    key: "orderNum",
    tag: "el-input-number",
    label: "显示顺序",
    props: {
      min: 0,
      required: true,
    },
  },
  {
    key: "path",
    tag: "el-input",
    label: "路由地址",
    props: {
      placeholder: "请输入路由地址",
    },
  },
  {
    key: "component",
    tag: "el-input",
    label: "组件路径",
    props: {
      placeholder: "请输入组件路径",
    },
  },
  {
    key: "perms",
    tag: "el-input",
    label: "权限标识",
    props: {
      placeholder: "请输入权限标识",
    },
  },
  {
    key: "visible",
    tag: "el-radio-group",
    label: "显示状态",
    options: [
      {
        id: "0",
        name: "显示",
      },
      {
        id: "1",
        name: "隐藏",
      },
    ],
  },
  {
    key: "status",
    tag: "el-radio-group",
    label: "启用状态",
    options: [
      {
        id: "0",
        name: "启用",
      },
      {
        id: "1",
        name: "停用",
      },
    ],
  },
]);

// 验证规则
const menuFormRules = {
  menuName: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
  orderNum: [{ required: true, message: "请输入显示顺序", trigger: "blur" }],
  menuType: [{ required: true, message: "请选择菜单类型", trigger: "blur" }],
};

// 初始化加载
onMounted(() => {
  fetchMenuList();
});

// 获取菜单列表
const fetchMenuList = async () => {
  loading.value = true;
  try {
    const params = {
      ...searchFormData,
      page: pagination.page,
      limit: pagination.limit,
    };
    const res: any = await menuApi.list();
    menubList.value = res;
    tableData.value = changeTree(res, 0);
    // pagination.total = res.total;
  } catch (error) {
  } finally {
    loading.value = false;
  }
};

// 搜索处理
const handleSearch = () => {
  pagination.page = 1;
  fetchMenuList();
};

// 重置搜索
const handleReset = () => {
  searchFormRef.value?.resetForm();
  pagination.page = 1;
  fetchMenuList();
};

// 分页变更
const handlePageChange = (val: any) => {
  pagination.page = val.page;
  pagination.limit = val.limit;
  fetchMenuList();
};

// 新增菜单
const handleAdd = () => {
  handleMenuTypeChange();
  isEdit.value = false;
  dialogTitle.value = "新增菜单";
  nextTick(() => {
    Object.assign(menuFormData, {
      id: undefined,
      menuName: "",
      parentId: 0,
      orderNum: 0,
      path: "",
      component: "",
      perms: "",
      status: "0",
      visible: "0",
      menuType: "M",
    });
  });
  dialogVisible.value = true;
};

// 新增菜单
const handleAdded = (row: any) => {
  handleMenuTypeChange();
  isEdit.value = false;
  dialogTitle.value = "新增菜单";
  Object.assign(menuFormData, {
    id: undefined,
    menuName: "",
    parentId: row.id,
    orderNum: 1,
    path: "",
    component: "",
    perms: "",
    status: "0",
    visible: "0",
    menuType: "M",
  });
  menuFormData.parentId = row.id;
  dialogVisible.value = true;
};

// 编辑菜单
const handleEdit = (row: any) => {
  isEdit.value = true;
  dialogTitle.value = "编辑菜单";
  Object.assign(menuFormData, { ...row });
  handleMenuTypeChange();
  dialogVisible.value = true;
};

// 保存菜单
const handleSave = async () => {
  try {
    await menuFormRef.value?.checkValidate();

    if (isEdit.value) {
      await menuApi.update(menuFormData);
      ElMessage.success("更新成功");
    } else {
      await menuApi.save(menuFormData);
      ElMessage.success("新增成功");
    }

    dialogVisible.value = false;
    fetchMenuList();
  } catch (error) {}
};

// 关闭对话框
const handleDialogClose = () => {
  menuFormRef.value?.resetForm();
};

// 删除菜单
const handleDelete = (row: any) => {
  ElMessageBox.confirm(`确定要删除菜单"${row.menuName}"吗？`, "确认删除", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      try {
        await menuApi.delete(row.id!);
        ElMessage.success("删除成功");
        fetchMenuList();
      } catch (error) {}
    })
    .catch(() => {
      // 用户取消删除
    });
};
</script>

<style scoped lang="scss">
.menu-management {
  padding: 20px;
}

.search-form {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
}

.dialog-footer {
  text-align: right;
}
</style>
